package com.lhkj.ct.meta.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.lhkj.ct.base.enums.GlobalStatus;
import com.lhkj.ct.base.exception.SystemException;
import com.lhkj.ct.base.model.Option;
import com.lhkj.ct.base.model.dto.PageQuery;
import com.lhkj.ct.base.mybatis.extension.service.impl.IServiceImpl;
import com.lhkj.ct.meta.admin.common.utils.DictUtils;
import com.lhkj.ct.meta.admin.mapper.SysDictDataMapper;
import com.lhkj.ct.meta.admin.mapper.SysDictTypeMapper;
import com.lhkj.ct.meta.admin.model.entity.TblDictData;
import com.lhkj.ct.meta.admin.model.entity.TblDictType;
import com.lhkj.ct.meta.admin.service.SysDictTypeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 字典类型表 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2023-09-07
 */
@Service
public class SysDictTypeServiceImpl extends IServiceImpl<SysDictTypeMapper, TblDictType> implements SysDictTypeService {

    @Resource
    private SysDictDataMapper dictDataMapper;

    /**
     * 项目启动时，初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        DictUtils.clearDictCache();
        loadingDictCache();
    }

    @Override
    public int insert(TblDictType entity) {
        int res = getBaseMapper().insert(entity);
        if (res > 0) {
            DictUtils.setDictOptionsCache(entity.getCode(), null);
        }
        return res;
    }

    @Override
    public int updateById(TblDictType entity) {
        TblDictType target = getById(entity.getId());
        int row = getBaseMapper().updateById(entity);
        if (row > 0 && !StringUtils.equals(target.getCode(), entity.getCode())) {
            dictDataMapper.update(null, new UpdateWrapper<TblDictData>()
                    .lambda().set(TblDictData::getTypeCode, entity.getCode())
                    .eq(TblDictData::getTypeCode, target.getCode())
            );
            List<Option<String>> dictDatas = dictDataMapper.listOptions(entity.getCode());
            DictUtils.setDictOptionsCache(entity.getCode(), dictDatas);
        }
        return row;
    }

    @Override
    public int removeByIds(Collection<? extends Serializable> idList) {
        int count = 0;
        for (Serializable dictId : idList) {
            TblDictType dictType = getById(dictId);
            if (dictDataMapper.countDictDataByType(dictType.getCode()) > 0) {
                throw new SystemException(String.format("%1$s已分配,不能删除", dictType.getName()));
            }
            count += removeById(dictId);
            DictUtils.removeDictCache(dictType.getCode());
        }
        return count;
    }

    @Override
    public IPage<TblDictType> selectDictTypePage(TblDictType tblDictType, PageQuery queryParams) {
        LambdaQueryWrapper<TblDictType> wrapper = new LambdaQueryWrapper<TblDictType>()
                .select(TblDictType::getId, TblDictType::getName, TblDictType::getCode, TblDictType::getStatus, TblDictType::getRemark)
                // 关键词搜索
                .like(StringUtils.isNotBlank(queryParams.getKeywords()), TblDictType::getName, queryParams.getKeywords())
                .or()
                .like(StringUtils.isNotBlank(queryParams.getKeywords()), TblDictType::getCode, queryParams.getKeywords());
        return getBaseMapper().selectPage(generatePage(queryParams), wrapper);
    }

    @Override
    public void resetDictCache() {
        DictUtils.clearDictCache();
        loadingDictCache();
    }

    @Override
    public void loadingDictCache() {
        List<TblDictData> sysDictData = dictDataMapper.selectList(
                new LambdaQueryWrapper<TblDictData>()
                        .eq(TblDictData::getStatus, GlobalStatus.NORMAL.getValue())
                        .orderByAsc(TblDictData::getSort)
        );
//        Map<String, List<TblDictData>> dictDataMap = sysDictData.stream().collect(Collectors.groupingBy(TblDictData::getTypeCode));
//        for (Map.Entry<String, List<TblDictData>> entry : dictDataMap.entrySet()) {
//            DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(TblDictData::getSort)).collect(Collectors.toList()));
//        }
        Map<String, List<Option<String>>> dictDataOptionsMap = sysDictData.stream().collect(Collectors.groupingBy(TblDictData::getTypeCode,
                Collectors.mapping(m-> new Option<String>(m.getValue(), m.getName()), Collectors.toList())));
        for (Map.Entry<String, List<Option<String>>> entry : dictDataOptionsMap.entrySet()) {
            DictUtils.setDictOptionsCache(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 校验字典类型称是否唯一
     *
     * @param dictType 字典类型
     * @return false为已存在，true为不重复
     */
    @Override
    public boolean checkTypeCodeUnique(TblDictType dictType) {
        TblDictType target = this.getBaseMapper().checkTypeCodeUnique(dictType.getCode());
        return (null == target || target.getId().equals(dictType.getId()));
    }

    @Override
    public List<TblDictType> options() {
        return getBaseMapper().selectList(
                new LambdaQueryWrapper<TblDictType>()
                .select(TblDictType::getCode, TblDictType::getName)
        );
    }
}
